#ifndef __ACTION_H_
#define __ACTION_H_

#include <boost/shared_ptr.hpp>
#include <cstring>

#include "MapProvider.h"

#define DEF(x) (x), 
enum {
#include "ActionDef.h"
	ACTION_INVALID
};
#undef DEF

static const char *actionID2Name(unsigned id)
{
#define DEF(x) if ((x) == id) return #x;
#include "ActionDef.h"
#undef DEF
	return NULL;
}

static unsigned actionName2ID(const char *name)
{
#define DEF(x) if (!strcmp(name, #x)) return x;
#include "ActionDef.h"
#undef DEF
	return ACTION_INVALID;
}

struct ActionBase
{
	virtual int cost() const = 0;
	virtual int execute(MapProvider &provider) const = 0;
	virtual unsigned actionID() const { return id; }
	unsigned id;
};

typedef boost::shared_ptr<ActionBase> ActionBasePtr;

struct ActionMove : public ActionBase
{
	ActionMove(int nx, int ny)
		: id(ACTION_MOVE), dx(nx), dy(ny) {}
	int dx;
	int dy;
	int cost() const;
	int execute(MapProvider &provider) const;
};

struct ActionAttack : public ActionBase
{
	ActionAttack(UnitBasePtr t)
		: id(ACTION_ATTACK), target(t) {}
	int cost() const;
	int execute(MapProvider &provider) const;
	UnitBasePtr target;
};

struct ActionGrow : public ActionBase
{
	ActionGrow()
		: id(ACTION_GROW) {}
	int cost() const;
	int execute(MapProvider &provider) const;
};

//	TODO
/*
struct ActionArm : public ActionBase
{
	ActionArm()
		: id(ACTION_ARM) {}
	int cost() const;
	int execute(MapProvider &provider) const;
};
*/

struct ActionSplit : public ActionBase
{
	ActionSplit(int a)
		: id(ACTION_SPLIT), amount(a) {}
	int cost() const;
	int execute(MapProvider &provider) const;
	int amount;
};

struct ActionMerge : public ActionBase
{
	ActionMerge(UnitBasePtr t)
		: id(ACTION_SPLIT), target(t) {}
	int cost() const;
	int execute(MapProvider &provider) const;
	UnitBasePtr target;
};

#endif